#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

int n, m;
int u, v, c;

const int MAXN = 310;

struct edge
{
    int to;
    int cost;
};


vector<edge> g[MAXN];
bool vis[MAXN];
int d[MAXN];

void prim()
{
    memset(d, 0x3f3f3f3f, sizeof(d));

    d[1] = 0;
    for (int i = 1; i < n; i++)
    {
        int k = 0;
        for (int j = 1; j <= n; j++)
        {
            if (!vis[j] && d[j] < d[k]) //找到距离最小的边
            {
                k = j;
            }
        }
        vis[k] = true;
        for (int j = 0; j < g[k].size(); j++)
        {
            auto temp = g[k][j];
            if (!vis[temp.to] && temp.cost < d[temp.to])
            {
                d[temp.to] = temp.cost;
            }
        }
    }
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> u >> v >> c;
        g[u].push_back({v, c});
        g[v].push_back({u, c});
    }
    prim();
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ans = max(ans, d[i]);
    }
    cout << n - 1 <<" "<< ans << endl;
    system("pause");
    return 0;
}